home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 429_01 / chess12 / chcharui.cpp < prev    next >
C/C++ Source or Header  |  1994-03-30  |  8KB  |  347 lines

  1. #include "misc.hpp"
  2. #include "brdsize.hpp"
  3. #include "charui.hpp"
  4. #include "chcharui.hpp"
  5.  
  6. CHESSCHARUSERIFACE ChessCharUI;
  7.  
  8. // internal representation of displayed board
  9. LOCAL class
  10.   {
  11.   public:
  12.     const char *pieceText;
  13.     BOOL selected;
  14.   }
  15. displayBoard[NUMROWS][NUMCOLS];
  16.  
  17. const char emptyText[] = "  ";
  18.  
  19. // width and height of a square of the displayed board, in character
  20. // cells
  21. const int POSITIONHEIGHT = 3;
  22. const int POSITIONWIDTH = 6;
  23.  
  24. // offsets in # of character cells of where to display the piece
  25. // abbreviation within the board square
  26. const int PIECETEXTROWOFFSET = 1;
  27. const int PIECETEXTCOLOFFSET = 2;
  28.  
  29. // the starting row and starting, ending column of the message
  30. // display area
  31. const int MSGSTARTROW = 1;
  32. const int MSGSTARTCOL = 50;
  33. const int MSGENDCOL = 78;
  34.  
  35. // returns TRUE if the board square corresponding to the given
  36. // board position should be displayed as white
  37. inline BOOL isWhite(POSITION board)
  38.   { return((board.row + board.col) & 1); }
  39.  
  40. void CHESSCHARUSERIFACE::initScreen(void)
  41.   {
  42.     POSITION board, screen, position;
  43.     BOOL inverse;
  44.  
  45.     // display empty board
  46.     screen.row = 0;
  47.     for (board.row = 0; board.row < NUMROWS; board.row++)
  48.       for (position.row = 0; position.row < POSITIONHEIGHT; position.row++)
  49.     {
  50.       screen.col = 0;
  51.       for (board.col = 0; board.col < NUMCOLS; board.col++)
  52.         {
  53.           inverse = isWhite(board);
  54.           for (position.col = 0; position.col < POSITIONWIDTH;
  55.            position.col++)
  56.         {
  57.           CharUI.showChar(screen, ' ', inverse);
  58.           screen.col++;
  59.         }
  60.         }
  61.       screen.row++;
  62.     }
  63.  
  64.     // initialize internal representation of displayed board
  65.     for (board.row = 0; board.row < NUMROWS; board.row++)
  66.       for (board.col = 0; board.col < NUMCOLS; board.col++)
  67.     {
  68.       displayBoard[board.row][board.col].pieceText = emptyText;
  69.       displayBoard[board.row][board.col].selected = FALSE;
  70.     }
  71.  
  72.     return;
  73.   }
  74.  
  75. // display piece abbrevation at given location on board
  76. LOCAL void showBoardText(POSITION where, const char *text, BOOL inverse)
  77.   {
  78.     where.row *= POSITIONHEIGHT;
  79.     where.row += PIECETEXTROWOFFSET;
  80.     where.col *= POSITIONWIDTH;
  81.     where.col += PIECETEXTCOLOFFSET;
  82.  
  83.     while (*text)
  84.       {
  85.     CharUI.showChar(where, *text, inverse);
  86.     text++;
  87.     where.col++;
  88.       }
  89.  
  90.     return;
  91.   }
  92.  
  93. void CHESSCHARUSERIFACE::showPiece(POSITION whereBoard, const char *abbrev)
  94.   {
  95.     BOOL inverse = isWhite(whereBoard);
  96.  
  97.     if (displayBoard[whereBoard.row][whereBoard.col].selected)
  98.       inverse = !inverse;
  99.  
  100.     showBoardText(whereBoard, abbrev, inverse);
  101.  
  102.     displayBoard[whereBoard.row][whereBoard.col].pieceText = abbrev;
  103.  
  104.     return;
  105.   }
  106.  
  107. void CHESSCHARUSERIFACE::clearPiece(POSITION whereBoard)
  108.   {
  109.     displayBoard[whereBoard.row][whereBoard.col].pieceText = emptyText;
  110.     showPiece(whereBoard, emptyText);
  111.  
  112.     return;
  113.   }
  114.  
  115. LOCAL int firstBlankMsgRow = MSGSTARTROW;
  116.  
  117. // clear last message displayed in message area
  118. LOCAL void clearLastMsg(void)
  119.   {
  120.     int row = MSGSTARTROW, col;
  121.  
  122.     while (row < firstBlankMsgRow)
  123.       {
  124.     for (col = MSGSTARTCOL; col <= MSGENDCOL; col++)
  125.       CharUI.showChar(row, col, ' ', FALSE);
  126.     row++;
  127.       }
  128.     firstBlankMsgRow = MSGSTARTROW;
  129.   }
  130.  
  131. // move to next character in message
  132. LOCAL inline void incTextList
  133.   (
  134.     // pointer to pointer to current string
  135.     const char **&textList,
  136.     // index of current character within current string
  137.     int &index
  138.   )
  139.   {
  140.     index++;
  141.     if (!(*textList)[index])
  142.       {
  143.     textList++;
  144.     index = 0;
  145.       }
  146.  
  147.     return;
  148.   }
  149.  
  150. // move to next blank space in message
  151. LOCAL int toEndWord
  152.   (
  153.     // pointer to pointer to current string
  154.     const char **&textList,
  155.     // index of current character within current string
  156.     int &index
  157.   )
  158.   {
  159.     int nChars = 0;
  160.  
  161.     if (!*textList)
  162.       return(0);
  163.  
  164.     while ((*textList)[index] == ' ')
  165.       {
  166.     incTextList(textList, index);
  167.     nChars++;
  168.     if (!*textList)
  169.       return(nChars);
  170.       }
  171.  
  172.     while ((*textList)[index] != ' ')
  173.       {
  174.     incTextList(textList, index);
  175.     nChars++;
  176.     if (!*textList)
  177.       return(nChars);
  178.       }
  179.  
  180.     return(nChars);
  181.   }
  182.  
  183. // display a message in the message area
  184. LOCAL void displayMsg
  185.   (
  186.     const char **textList
  187.   )
  188.   {
  189.     int row = MSGSTARTROW, col = MSGSTARTCOL;
  190.     int showIndex = 0, lookIndex = 0, nChars;
  191.     const char **lookList = textList;
  192.  
  193.     clearLastMsg();
  194.  
  195.     while (*textList)
  196.       {
  197.     nChars = toEndWord(lookList, lookIndex);
  198.  
  199.     if ((col + nChars) > (MSGENDCOL + 1))
  200.       {
  201.         // go to next line in message area
  202.         row++;
  203.         col = MSGSTARTCOL;
  204.         while ((*textList)[showIndex] == ' ')
  205.           incTextList(textList, showIndex);
  206.       }
  207.  
  208.     for ( ; ; )
  209.       {
  210.         if (textList == lookList)
  211.           if (showIndex == lookIndex)
  212.         break;
  213.         CharUI.showChar(row, col++, (*textList)[showIndex], FALSE);
  214.         incTextList(textList, showIndex);
  215.       }
  216.       }
  217.  
  218.     firstBlankMsgRow = row + 1;
  219.  
  220.     return;
  221.   }
  222.  
  223. void CHESSCHARUSERIFACE::showMessage
  224.   (
  225.     const char **textList
  226.   )
  227.   {
  228.     displayMsg(textList);
  229.  
  230.     return;
  231.   }
  232.  
  233. void CHESSCHARUSERIFACE::clearMessage(void)
  234.   {
  235.     clearLastMsg();
  236.  
  237.     return;
  238.   }
  239.  
  240. BOOL CHESSCHARUSERIFACE::showMessage
  241.   (
  242.     const char **textList,
  243.     const char *keyList,
  244.     uint *keyIndex
  245.   )
  246.   {
  247.     uint keyPressed, i;
  248.  
  249.     displayMsg(textList);
  250.  
  251.     for ( ; ; )
  252.       {
  253.     keyPressed = CharUI.readKey();
  254.  
  255.         if (keyPressed == KEYESC)
  256.       return(FALSE);
  257.  
  258.     if (!keyList)
  259.       return(TRUE);
  260.  
  261.     for (i = 0; keyList[i]; i++)
  262.       {
  263.         if (keyList[i] == (char) keyPressed)
  264.           {
  265.         *keyIndex = i;
  266.         return(TRUE);
  267.           }
  268.       }
  269.       }
  270.   }
  271.  
  272. void CHESSCHARUSERIFACE::setSelect(POSITION whereBoard)
  273.   {
  274.     showBoardText
  275.       (
  276.     whereBoard,
  277.     displayBoard[whereBoard.row][whereBoard.col].pieceText,
  278.     !isWhite(whereBoard)
  279.       );
  280.     displayBoard[whereBoard.row][whereBoard.col].selected = TRUE;
  281.  
  282.     return;
  283.   }
  284.  
  285. void CHESSCHARUSERIFACE::clearSelect(POSITION whereBoard)
  286.   {
  287.     showBoardText
  288.       (
  289.     whereBoard,
  290.     displayBoard[whereBoard.row][whereBoard.col].pieceText,
  291.     isWhite(whereBoard)
  292.       );
  293.     displayBoard[whereBoard.row][whereBoard.col].selected = FALSE;
  294.  
  295.     return;
  296.   }
  297.  
  298. BOOL CHESSCHARUSERIFACE::selectPosition
  299.   (
  300.     const char **textList,
  301.     POSITION &whereBoard
  302.   )
  303.   {
  304.     uint keyPressed;
  305.  
  306.     displayMsg(textList);
  307.  
  308.     for ( ; ; )
  309.       {
  310.     showBoardText
  311.       (
  312.         whereBoard,
  313.         displayBoard[whereBoard.row][whereBoard.col].pieceText,
  314.         !isWhite(whereBoard)
  315.       );
  316.     keyPressed = CharUI.readKey();
  317.         if (keyPressed == KEYENTER)
  318.       {
  319.         displayBoard[whereBoard.row][whereBoard.col].selected =
  320.           TRUE;
  321.         return(TRUE);
  322.       }
  323.     if (!displayBoard[whereBoard.row][whereBoard.col].selected)
  324.       showBoardText
  325.         (
  326.           whereBoard,
  327.           displayBoard[whereBoard.row][whereBoard.col].pieceText,
  328.           isWhite(whereBoard)
  329.         );
  330.  
  331.         if (keyPressed == KEYESC)
  332.       return(FALSE);
  333.  
  334.     if ((keyPressed == KEYUP) && (whereBoard.row != 0))
  335.       whereBoard.row--;
  336.     else if ((keyPressed == KEYDOWN) &&
  337.                  (whereBoard.row != (NUMROWS - 1)))
  338.       whereBoard.row++;
  339.     else if ((keyPressed == KEYLEFT) &&
  340.                  (whereBoard.col != 0))
  341.       whereBoard.col--;
  342.     else if ((keyPressed == KEYRIGHT) &&
  343.                  (whereBoard.col != (NUMCOLS - 1)))
  344.       whereBoard.col++;
  345.       }
  346.   }
  347.